<template>
  <section class="page-container">
    <section class="options-wrap">
      <span
        :class="[
          'the-radio-button',
          is3DScene ? 'active' : ''
        ]"
        @click="handle3DScene"
      >
        三维模型
      </span>
      <span
        :class="[
          'the-radio-button',
          is3DScene ? '' : 'active'
        ]"
        @click="handle2DScene"
      >
        二维模型
      </span>
    </section>
    <section
      id="cesiumContainer"
      class="cesium-container"
    />
  </section>
</template>

<script lang="ts">
import { defineComponent, onMounted, ref } from 'vue';

declare let Cesium: any;
declare let CesiumNavigation: any;

Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIxNTEwOWY3My0zZjllLTQxMzEtYjM4NC0xZjU3NzE2ZDliZjQiLCJpZCI6ODY1NTEsImlhdCI6MTY0Nzg2OTgxOH0.uo8OVOsZM9nmMEYGUXvl82VUUYglbb1PBI-eehyzsik';

export default defineComponent({
  setup() {
    const is3DScene = ref(true);
    let tileset: any;
    let viewer: any;

    const handle3DScene = () => {
      if (is3DScene.value) {
        return;
      }
      is3DScene.value = true;
      viewer.scene.mode = Cesium.SceneMode.SCENE3D;
      viewer.zoomTo(tileset, {
        heading: Cesium.Math.toRadians(0.0),
        pitch: Cesium.Math.toRadians(-50.0),
        range: 1000,
      });
      // 将视锥体/投影切换为透视
      viewer.camera.switchToPerspectiveFrustum();
      viewer.scene.screenSpaceCameraController.enableTilt = true;
    };

    const handle2DScene = () => {
      if (!is3DScene.value) {
        return;
      }
      is3DScene.value = false;
      viewer.zoomTo(tileset, {
        heading: Cesium.Math.toRadians(0.0),
        pitch: Cesium.Math.toRadians(-90.0),
        range: 900,
      });
      // 将平截头体/投影切换为正交
      viewer.camera.switchToOrthographicFrustum();
      viewer.scene.screenSpaceCameraController.enableTilt = false;
    };

    const setMpViewer = () => {
      viewer.imageryLayers.removeAll();
      viewer.cesiumWidget.creditContainer.style.display = 'none';
      viewer.scene.globe.show = true;
      viewer.scene.globe.baseColor = new Cesium.Color(0, 0, 0, 0);
      viewer.scene.backgroundcolor = new Cesium.Color(0, 0, 0, 0);
      viewer.scene.globe.enableLighting = false;
      viewer.scene.globe.showGroundAtmosphere = false;
      viewer.scene.screenSpaceCameraController.enableCollisionDetection = true;
      viewer.scene.globe.translucency.enabled = true;
      viewer.scene.globe.undergroundColor = undefined;

      // 否开启抗锯齿
      viewer.scene.globe.maximumScreenSpaceError = 4 / 3;
      viewer.scene.globe.depthTestAgainstTerrain = true;

      viewer.scene.screenSpaceCameraController.zoomEventTypes = [
        Cesium.CameraEventType.WHEEL,
        Cesium.CameraEventType.PINCH
      ];
      // 倾斜视图 鼠标右键旋转
      viewer.scene.screenSpaceCameraController.tiltEventTypes = [
        Cesium.CameraEventType.RIGHT_DRAG,
        Cesium.CameraEventType.PINCH,
        {
          eventType: Cesium.CameraEventType.LEFT_DRAG,
          modifier: Cesium.KeyboardEventModifier.CTRL,
        }
      ];
    };

    const handleFlyToViewer = () => {
      viewer.zoomTo(tileset, {
        heading: Cesium.Math.toRadians(0.0),
        pitch: Cesium.Math.toRadians(-90.0),
        range: 900,
      });
    };

    const add3DTile = (url: string) => new Cesium.Cesium3DTileset({
      url,
      /*
         * maximumScreenSpaceError: 1,
         * maximumMemoryUsage: 512,
         * preferLeaves: true,
         * skipLevelOfDetail: true,
         * skipLevels: 16,
         * loadSiblings: false,
         * cullWithChildrenBounds: true,
         */
      skipLevelOfDetail: true,
      baseScreenSpaceError: 1024,
      maximumScreenSpaceError: 1, // 数值加大，能让最终成像变模糊
      skipScreenSpaceErrorFactor: 16,
      skipLevels: 1,
      immediatelyLoadDesiredLevelOfDetail: false,
      loadSiblings: true, // 如果为true则不会在已加载完概况房屋后，自动从中心开始超清化房屋
      cullWithChildrenBounds: true,
      cullRequestsWhileMoving: true,
      cullRequestsWhileMovingMultiplier: 10, // 值越小能够更快的剔除
      preloadWhenHidden: true,
      preferLeaves: true,
      maximumMemoryUsage: 512, // 内存分配变小有利于倾斜摄影数据回收，提升性能体验
      progressiveResolutionHeightFraction: 0.5, // 数值偏于0能够让初始加载变得模糊
      dynamicScreenSpaceErrorDensity: 0.1, // 数值加大，能让周边加载变快
      dynamicScreenSpaceErrorFactor: 1,
      dynamicScreenSpaceError: true, // 有了这个后，会在真正的全屏加载完之后才清晰化房屋
    });

    const initCompass = () => {
      const options = {
        enableCompass: true,
        enableZoomControls: false,
        enableDistanceLegend: false,
        enableCompassOuterRing: true,
      };
        // eslint-disable-next-line no-new
      new CesiumNavigation(viewer, options);
    };

    const initCesium = () => {
      viewer = new Cesium.Viewer('cesiumContainer', {
        baseLayerPicker: false, // 如果设置为false，将不会创建右上角图层按钮。
        geocoder: false, // 如果设置为false，将不会创建右上角查询(放大镜)按钮。
        navigationHelpButton: false, // 如果设置为false，则不会创建右上角帮助(问号)按钮，操作提示的功能。
        homeButton: false, // 如果设置为false，将不会创建右上角主页(房子)按钮，类似于重置视角的功能
        sceneModePicker: false, // 如果设置为false，将不会创建右上角投影方式控件(显示二三维切换按钮)。
        animation: false, // 如果设置为false，将不会创建左下角动画小部件。
        timeline: false, // 如果设置为false，则不会创建正下方时间轴小部件。
        fullscreenButton: false, // 如果设置为false，将不会创建右下角全屏按钮。
        scene3DOnly: false, // 为 true 时，每个几何实例将仅以3D渲染以节省GPU内存。
        /**
         * 默认true ，否则为 false 。
         *   此选项优先于设置 Viewer＃clockViewModel 。
         *   ps. Viewer＃clockViewModel 是用于控制当前时间的时钟视图模型。我们这里用不到时钟，就把shouldAnimate设为false
         *
        */
        shouldAnimate: true,
        infoBox: false, // 是否显示点击要素之后显示的信息
        skyBox: false, // 控制天气是否显示
        skyAtmosphere: false,
        sceneMode: 3, // 初始场景模式 1 2D模式 2 2D循环模式 3 3D模式  this.Cesium.SceneMode
        requestRenderMode: false, // 启用请求渲染模式，不需要渲染，节约资源吧
        selectionIndicator: false, // 关闭绿色选择框
        orderIndependentTranslucency: false,
        useBrowserRecommendedResolution: false,

      });
      // (viewer as any)._cesiumWidget._creditContainer.style.display = 'none'; // Cesuim隐藏底部的logo和版本信息
      viewer.cesiumWidget.creditContainer.remove(); // Cesuim隐藏底部的logo和版本信息

      setMpViewer();
      const url = 'https://dony.online/static/js/cesium/changsha_b3dms/tileset.json';
      add3DTile(url);
      tileset = add3DTile(url);
      tileset.readyPromise.then((model: any) => {
        viewer.scene.primitives.add(model);
        // 判断是否是首次加载，首次加载调用handleFlyToViewer使用固定视角，否则不切换视角
        handleFlyToViewer();
      }).catch((error: Error) => {
        console.log(error);
      });
      initCompass();
    };
    onMounted(() => {
      initCesium();
    });
    return {
      is3DScene,
      handle3DScene,
      handle2DScene,
    };
  },
});
</script>
<style lang="scss" scoped>
.page-container {
  position: relative;
  height: 100%;
  padding: 0;

  .cesium-container {
    height: 100%;
  }

  .options-wrap {
    position: absolute;
    top: 12px;
    left: 12px;
    z-index: 999;
    display: flex;
    align-items: center;
    justify-content: space-between;

    .the-radio-button {
      box-sizing: border-box;
      padding: 0 15px;
      font-size: 12px;
      line-height: 26px;
      cursor: pointer;
      background-color: #fff;
      border: 1px solid #ececec;
      border-radius: 2px;

      &.active {
        color: #fff;
        background-color: var(--maia-menu-active-text-color);
        border-color: var(--maia-menu-active-text-color);
      }
    }

    .hover {
      margin-left: 10px;
      font-size: 18px;
      cursor: pointer;
    }
  }
}
</style>
